package services;

import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import repositories.AdministratorRepository;
import security.LoginService;
import security.UserAccount;
import domain.Administrator;
import domain.Evaluation;
import domain.Event;
import domain.Registration;
import domain.Route;
import forms.AdministratorForm;

@Service
@Transactional
public class AdministratorService {

	// Managed repository -----------------------------------------------------
	@Autowired
	private Md5PasswordEncoder encoder;

	@Autowired
	private AdministratorRepository administratorRepository;

	@Autowired
	private EventService eventService;

	@Autowired
	private RouteService routeService;

	// Constructors -----------------------------------------------------------

	public AdministratorService() {
		super();
	}

	// Simple CRUD methods ----------------------------------------------------

	public Administrator create() {
		return new Administrator();
	}

	public void save(Administrator a) {
		Assert.notNull(a);
		if (a.getId() == 0)
			a.getUserAccount().setPassword(
					encoder.encodePassword(a.getUserAccount().getPassword(),
							null));
		administratorRepository.save(a);
	}

	// Other business methods -------------------------------------------------

	public Administrator findByPrincipal() {
		UserAccount u = LoginService.getPrincipal();
		Administrator a = administratorRepository
				.findByUserAccountId(u.getId());
		return a;
	}

	public void computeRating() {
		Assert.isTrue(findByPrincipal().getClass() == Administrator.class);
		Collection<Event> le = eventService.findAll();
		Collection<Route> lr = routeService.findAll();
		Double res = 0.0;
		int cont = 0;
		// Registration -------------------------------------
		for (Event event : le) {
			Collection<Registration> registrations = event.getRegistrations();
			res = 0.0;
			cont = 0;
			for (Registration registration : registrations) {
				
				if (registration.getAssessment() != null) {
					res += registration.getAssessment().getRating();
					cont++;
				}
				
			}
			res = res / cont;

			if (cont != 0) {
				event.setRating(res);
				eventService.saveRating(event);
			}
		}

		for (Route route : lr) {
			res = 0.0;
			cont = 0;
			for (Evaluation evaluation : route.getEvaluations()) {
				
				if (evaluation.getAssessment() != null) {
					res += evaluation.getAssessment().getRating();
					cont++;
				}
				
			}
			res = res / cont;

			if (cont != 0) {
				route.setRating(res);
				routeService.saveRating(route);
			}

		}
	}
	
	public AdministratorForm getFormObject(Administrator admin){
		AdministratorForm res;
		
		res = new AdministratorForm();
		res.setId(admin.getId());
		res.setEmail(admin.getEmail());
		res.setName(admin.getName());
		res.setSurname(admin.getSurname());
		res.setUserAccount(admin.getUserAccount());
		res.setVersion(admin.getVersion());
		
		return res;
	}
	
	public Administrator reconstruct(AdministratorForm administratorForm){
		Administrator res;
		
		if(administratorForm.getId()!=0)
			res = administratorRepository.findOne(administratorForm.getId());
		else
			res = create();
		
		res.setEmail(administratorForm.getEmail());
		res.setName(administratorForm.getName());
		res.setSurname(administratorForm.getSurname());
		res.setVersion(administratorForm.getVersion());
		res.setUserAccount(administratorForm.getUserAccount());
		res.setId(administratorForm.getId());
		
		return res;
	}
}
